import pandas as pd
from app.config import Config


# 自定义异常类，用于抛出那些在运行过程中有意探知原因后需要对外告知原因的“错误”
class InnerReportException(Exception):
    def __init__(self, msg):
        self.msg = msg

    def __str__(self):
        return self.msg


# 表字段中文名→英文名
def upload_field_corr(upload_df, table_zh_name, yuanshi_dict_path=Config.FIELD_DICT_FILE):
    base_name_df = pd.read_excel(yuanshi_dict_path, table_zh_name, header=1)
    # 创建从中文名到英文名的映射字典
    column_name_map = base_name_df.set_index('释义')['字段名'].to_dict()
    # 使用映射字典重命名upload_df的列名，中文名（释义）→英文名（字段名）
    for old_col, new_col in column_name_map.items():
        if old_col in upload_df.columns:
            upload_df.rename(columns={old_col: new_col}, inplace=True)
    return upload_df


# 表字段英文名→中文名
def uploaded_field_corr_entozh(upload_df, table_zh_name, yuanshi_dict_path=Config.FIELD_DICT_FILE):
    base_name_df = pd.read_excel(yuanshi_dict_path, table_zh_name, header=1)
    # 创建从中文名到英文名的映射字典
    column_name_map = base_name_df.set_index('字段名')['释义'].to_dict()
    # 使用映射字典重命名upload_df的列名，中文名（释义）→英文名（字段名）
    for old_col, new_col in column_name_map.items():
        if old_col in upload_df.columns:
            upload_df.rename(columns={old_col: new_col}, inplace=True)
    return upload_df


# 加工报表表字段英文名→中文名
def uploaded_field_corr_entozh_res(upload_df, table_zh_name, shuchu_dict_path=Config.PROCSSED_FIELD_DICT_FILE):
    base_name_df = pd.read_excel(shuchu_dict_path, table_zh_name, header=1)
    # 创建从中文名到英文名的映射字典
    column_name_map = base_name_df.set_index('字段名')['释义'].to_dict()
    column_name_map["row_count"] = "数据记录数量"
    # 使用映射字典重命名upload_df的列名，中文名（释义）→英文名（字段名）
    for old_col, new_col in column_name_map.items():
        if old_col in upload_df.columns:
            upload_df.rename(columns={old_col: new_col}, inplace=True)
    return upload_df


def format_number(value):
    if isinstance(value, int):
        return str(value)
    elif isinstance(value, float):
        if abs(value) > 0.1:
            if value % 1 != 0:
                return str("{:.2f}".format(value))  # 大于0.1保留两位小数
            else:
                return int(value)
        else:
            if value == 0:
                return str(0)
            else:
                return str("{:.2e}".format(value))  # 小于等于0.1转化为科学计数法
    else:
        return value
    pass
